# -*- coding: utf-8 -*-
"""splitter_mixin
PDF 拆分线程功能模块。
将 main.py 中 def split_pdf_thread(...) 全部代码剪切粘贴到本类内部。
"""

import os
import traceback
from tkinter import messagebox
import fitz  # PyMuPDF


class SplitterMixin:
    """PDF 拆分相关方法 mixin"""
    def split_pdf_thread(self, output_dir, range_str, split_each_page):
        """执行PDF拆分的核心功能的线程"""
        try:
            output_suffix = self.output_name_entry.get().strip()

            # 创建输出目录
            os.makedirs(output_dir, exist_ok=True)

            total_files = len(self.split_files)
            processed_files = 0
            successful_files = 0
            failed_files_info = {}  # Store filename: error message

            for file_index, input_path in enumerate(self.split_files):
                file_name = os.path.basename(input_path)
                base_name = os.path.splitext(file_name)[0]
                # 简单的安全名称处理：替换常见非法字符
                safe_name = "".join(c if c.isalnum() or c in (' ', '_', '-') else '_' for c in base_name).rstrip()
                if not safe_name: safe_name = "untitled"  # Handle cases where all chars are replaced

                current_file_failed = False
                try:
                    # 更新状态
                    status_text = f"处理中: {file_name} ({file_index + 1}/{total_files})"
                    self.after(0, self.update_progress_safe, file_index / total_files, status_text)

                    doc = fitz.open(input_path)
                    max_pages = doc.page_count

                    if split_each_page:
                        # --- 每页单独拆分 ---
                        pdf_output_subdir = os.path.join(output_dir, safe_name)  # 每个PDF一个子目录
                        os.makedirs(pdf_output_subdir, exist_ok=True)
                        for page_num in range(max_pages):
                            new_doc = fitz.open()
                            new_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)
                            output_page_path = os.path.join(pdf_output_subdir, f"{safe_name}_第{page_num + 1}页.pdf")
                            new_doc.save(output_page_path, garbage=3, deflate=True)
                            new_doc.close()
                            # 可以添加页内进度更新，但可能会过于频繁
                            # inner_progress = (file_index + (page_num + 1) / max_pages) / total_files
                            # self.after(0, self.update_progress_safe, inner_progress, status_text + f" - 页 {page_num+1}")

                    else:
                        # --- 按范围拆分 ---
                        # 使用新方法解析多个独立的范围组
                        range_groups = self.parse_page_range_groups(range_str, max_pages)
                        if not range_groups:
                            raise ValueError("未指定有效的页面范围或解析失败")

                        # 为每个范围组创建一个单独的PDF文件
                        for group_index, pages_to_extract in enumerate(range_groups, start=1):
                            new_doc = fitz.open()

                            # Add pages in the order specified by pages_to_extract
                            for page_num in pages_to_extract:
                                # Ensure page_num is within valid range (0 to max_pages-1)
                                if 0 <= page_num < max_pages:
                                    new_doc.insert_pdf(doc, from_page=page_num, to_page=page_num)
                                else:
                                    # This should ideally not happen if parse_page_range_groups is correct
                                    print(f"警告: 跳过无效页码 {page_num + 1} (文件: {file_name})")

                            if len(new_doc) > 0:  # Only save if pages were added
                                # 生成输出文件名
                                # 如果只有一个范围组，使用原有的命名方式；多个范围组时添加序号
                                if len(range_groups) == 1:
                                    # 单个范围组，使用后缀
                                    if output_suffix:
                                        output_path = os.path.join(output_dir, f"{safe_name}{output_suffix}.pdf")
                                    else:
                                        effective_suffix = "_split"
                                        output_path = os.path.join(output_dir, f"{safe_name}{effective_suffix}.pdf")
                                else:
                                    # 多个范围组，添加序号
                                    # 计算页码范围用于文件名
                                    first_page = pages_to_extract[0] + 1  # Convert to 1-based
                                    last_page = pages_to_extract[-1] + 1
                                    if first_page == last_page:
                                        page_range_str = f"第{first_page}页"
                                    else:
                                        page_range_str = f"第{first_page}-{last_page}页"

                                    if output_suffix:
                                        output_path = os.path.join(output_dir, f"{safe_name}_{page_range_str}{output_suffix}.pdf")
                                    else:
                                        output_path = os.path.join(output_dir, f"{safe_name}_{page_range_str}.pdf")

                                new_doc.save(output_path, garbage=3, deflate=True)
                            else:
                                print(f"警告: 文件 {file_name} 范围组 {group_index} 没有提取任何页面，未生成输出。")

                            new_doc.close()

                        # 检查是否所有范围组都没有生成有效输出
                        if not any(len(self.parse_page_range_groups(range_str, max_pages)) > 0 for _ in range_groups):
                            current_file_failed = True
                            failed_files_info[file_name] = "没有符合范围的页面被提取"

                    doc.close()

                except ValueError as ve:  # Handle range parsing errors specifically
                    print(f"处理文件 {file_name} 时出错: {str(ve)}")
                    current_file_failed = True
                    failed_files_info[file_name] = f"页面范围错误: {str(ve)}"
                    # Optionally close doc if open
                    if 'doc' in locals() and doc.is_open:
                        doc.close()
                except Exception as e:
                    print(f"处理文件 {file_name} 时发生未知错误: {str(e)}")
                    print(traceback.format_exc())
                    current_file_failed = True
                    failed_files_info[file_name] = f"处理错误: {str(e)}"
                    # Optionally close doc if open
                    if 'doc' in locals() and doc.is_open:
                        doc.close()

                processed_files += 1
                if not current_file_failed:
                    successful_files += 1

            # --- 处理完成 ---
            final_progress = 1.0
            final_status = "拆分完成"
            self.after(0, self.update_progress_safe, final_progress, final_status)

            # 显示最终结果消息
            if failed_files_info:
                error_details = "\n失败文件详情:\n" + "\n".join(
                    [f"- {fname}: {emsg}" for fname, emsg in failed_files_info.items()])
                warning_message = (
                    f"拆分完成！\n\n成功: {successful_files} 个文件\n失败: {len(failed_files_info)} 个文件\n"
                    f"文件保存在: {output_dir}\n{error_details}")
                self.after(0, messagebox.showwarning, "部分完成", warning_message)
            else:
                success_message = (f"PDF拆分成功！\n\n已处理 {successful_files} 个文件\n"
                                   f"文件保存在: {output_dir}")
                self.after(0, messagebox.showinfo, "完成", success_message)

        except Exception as e:
            # 捕获线程级别的意外错误
            error_details = traceback.format_exc()
            self.after(0, self.show_error_message, f"拆分过程中发生严重错误: {str(e)}\n{error_details}")
            self.after(0, self.update_progress_safe, 0, "拆分失败")  # Reset progress on major failure

        finally:
            # 重置UI状态 (总是在主线程中执行)
            self.after(0, self.reset_ui_state, self.split_btn, self.split_progress, self.split_status, "准备就绪")
